//! Group database traits.

use openmls::group::GroupId;

use super::types::*;
use crate::errors::Error;

/// Group cryptographic data store.
pub trait GroupKeyDb {
    /// Sets up whatever needs to be set up for a new group.
    fn init_group(&self, group_id: &GroupId) -> Result<(), Error>;

    /// Purge all state entries we have about a group, returning the number of
    /// entries removed.
    fn purge_group(&self, group_id: &GroupId) -> Result<u64, Error>;

    /// Gets a key within a group.
    fn get_key(&self, group_id: &GroupId, key: &[u8]) -> Result<Option<Vec<u8>>, Error>;

    /// Applies an update to a batch of keys.
    fn apply_batch(&self, group_id: &GroupId, batch: KeyUpdateBatch) -> Result<(), Error>;
}

/// Group message output.
pub trait GroupOutputDb {
    /// Sets up whatever needs to be set up for a new group.
    fn init_group(&self, group_id: &GroupId) -> Result<(), Error>;

    /// Purge all output messages we have about a group, returning the number of
    /// entries removed.
    fn purge_group(&self, group_id: &GroupId) -> Result<u64, Error>;

    /// Writes a message into the database, returning its index.
    fn write_next_entry(&self, group_id: &GroupId, msg: MsgEntry) -> Result<GroupMsgId, Error>;

    /// Gets an entry, if it exists.
    fn get_entry(&self, group_id: &GroupId, msg_id: GroupMsgId) -> Result<Option<MsgEntry>, Error>;

    /// Gets the message as the specified position, and the following n messages
    /// until we reach a message that's not stored.
    fn get_entry_range(
        &self,
        group_id: &GroupId,
        start_id: GroupMsgId,
        count: u64,
    ) -> Result<Vec<MsgEntry>, Error>;
}
